package com.heima.article.service.impl;

import com.alibaba.fastjson.JSON;
import com.heima.apis.wemedia.IWemediaClient;
import com.heima.article.mapper.ApArticleMapper;
import com.heima.article.service.HotArticleService;
import com.heima.common.constants.ArticleConstants;
import com.heima.common.redis.CacheService;
import com.heima.model.article.pojos.ApArticle;
import com.heima.model.article.vos.HotArticleVo;
import com.heima.model.common.dtos.ResponseResult;
import com.heima.model.wemedia.pojos.WmChannel;
import lombok.extern.slf4j.Slf4j;
import org.checkerframework.checker.units.qual.C;
import org.joda.time.DateTime;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import java.time.LocalDate;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * create 2023/6/28 22:31
 */


@Slf4j
@Service
@Transactional
public class HotArticleServiceImpl implements HotArticleService {

    @Autowired
    private ApArticleMapper apArticleMapper;

    @Autowired
    private IWemediaClient mediaClient;

    /**
     * 计算热点文章
     */


    public void computeHotArticle() {
        //1.查询前5天的文章数据
//        Date date = DateTime.now().minusDays(5).toDate();
        Date date= DateTime.now().minusYears(3).toDate();
        List<ApArticle> apArticleList = apArticleMapper.findArticleListByLast5days(date);
        //2.计算文章的分值
        List<HotArticleVo> hotArticleVoList = computeArticleScore(apArticleList);
        //3.为每个频道缓存30条分值较高的文章
        sortAndCache(hotArticleVoList);
    }

    @Autowired
    private CacheService cacheService;

    //排序和缓存文章信息
    private void sortAndCache(List<HotArticleVo> hotArticleVoList) {
        if (CollectionUtils.isEmpty(hotArticleVoList)) {
            return;
        }
        Collections.sort(hotArticleVoList, new Comparator<HotArticleVo>() {
            @Override
            public int compare(HotArticleVo o1, HotArticleVo o2) {
                return o2.getScore() - o1.getScore();
            }
        });
        ResponseResult result = mediaClient.getChannels();
        if (!Objects.equals(200, result.getCode())) {
            throw new RuntimeException("远程调用查询频道出错");
        }
        Object data = result.getData();
        if (data == null) {
            return;
        }
        String channelJson = JSON.toJSONString(data);
        List<WmChannel> wmChannels = JSON.parseArray(channelJson, WmChannel.class);
        if (CollectionUtils.isEmpty(wmChannels)) {
            return;
        }
        for (WmChannel wmChannel : wmChannels) {
            //过滤每个频道的数据
            List<HotArticleVo> articleVos = hotArticleVoList.stream().filter(item -> item.getChannelId().equals(wmChannel.getId())).limit(30).collect(Collectors.toList());
            cacheService.set(ArticleConstants.HOT_ARTICLE_FIRST_PAGE + wmChannel.getId(), JSON.toJSONString(articleVos));
        }
        cacheService.set(ArticleConstants.DEFAULT_TAG, JSON.toJSONString(hotArticleVoList));
    }

    private List<HotArticleVo> computeArticleScore(List<ApArticle> apArticleList) {
        ArrayList<HotArticleVo> hotArticleVos = new ArrayList<>();
        for (ApArticle apArticle : apArticleList) {
            HotArticleVo hotArticleVo = new HotArticleVo();
            BeanUtils.copyProperties(apArticle, hotArticleVo);
            Integer score = computeScore(apArticle);
            hotArticleVo.setScore(score);
            hotArticleVos.add(hotArticleVo);
        }
        return hotArticleVos;
    }

    private Integer computeScore(ApArticle apArticle) {
        int score = 0;
        Integer views = apArticle.getViews();
        if (views != null) {

            score += views;
        }
        Integer comment = apArticle.getComment();
        if (comment != null) {
            score += comment * ArticleConstants.HOT_ARTICLE_COMMENT_WEIGHT;
        }
        Integer collection = apArticle.getCollection();
        if (collection != null) {
            score += collection * ArticleConstants.HOT_ARTICLE_COLLECTION_WEIGHT;
        }
        Integer likes = apArticle.getLikes();
        if (likes != null) {
            score += likes * ArticleConstants.HOT_ARTICLE_LIKE_WEIGHT;
        }
        return score;

    }
}
